package com.tcm.controller.backend;

import com.tcm.common.enums.ResponseEnum;
import com.tcm.entity.Book;
import com.tcm.entity.dto.BookUpdateDto;
import com.tcm.entity.vo.BookListResult;
import com.tcm.entity.resp.R;
import com.tcm.exception.DatabaseOperationException;
import com.tcm.service.BookService;
import com.tcm.utils.AccessTokenUtil;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;

/**
 * 书籍（课程）管理控制器
 * @author Guqier
 * @version 1.0
 * @date 2023/7/10 18:02
 */
@Data
@RestController
@RequestMapping("/pc/book")
public class BookController {

    @Autowired
    private BookService bookService;

    /**
     * 添加课程信息
     * @param name 课程名称
     * @param sequence 排序，可选
     * @param file 封面文件
     * @param request http请求对象
     * @return 响应信息
     */
    @RequestMapping(value = "/course", method = RequestMethod.POST)
    public R addCourseInfo(@RequestParam String name, @RequestParam Integer sequence, @RequestParam MultipartFile file, HttpServletRequest request){
        boolean res = false;
        try {
            res = bookService.addCourseInfo(name, sequence, file, AccessTokenUtil.getUserId(request));
        } catch (Exception e) {
            return R.fail(0, e.getMessage());
        }
        return res ? R.success() : R.fail(ResponseEnum.DATABASE_OPERATION_FAIL);
    }

    /**
     * 通过ID删除课程（顶级节点）
     * @param id 课程ID
     * @param request http请求对象
     * @return 响应结果
     */
    @RequestMapping(value = "/course", method = RequestMethod.DELETE)
    public R removeCourseInfo(Long id, HttpServletRequest request){
        boolean res = false;
        try {
            res = bookService.removeCourseInfo(id, AccessTokenUtil.getUserId(request));
        } catch (Exception e) {
            return R.fail(0, e.getMessage());
        }
        return res ? R.success() : R.fail(102, "课程不存在或不属于课程");
    }

    /**
     * 获取课程信息列表（顶级节点）
     * @return 课程信息列表
     */
    @RequestMapping(value = "/course", method = RequestMethod.GET)
    public R getCourseInfoList(){
        List<BookListResult> courseList = bookService.getCourseList();
        return R.success(courseList);
    }

    /**
     * 修改课程信息
     * @param id 课程ID
     * @param name 课程名称
     * @param sequence 课程同层级排序
     * @param file 封面，可选，为空则不修改
     * @param request http请求对象
     * @return 响应结果
     */
    @RequestMapping(value = "/course",method = RequestMethod.PUT)
    public R modifyCourseInfo(@RequestParam Long id, @RequestParam String name, @RequestParam Integer sequence, @RequestParam(required = false) MultipartFile file, HttpServletRequest request){
        boolean res = false;
        try {
            res = bookService.modifyCourseInfo(id, name, sequence, file, AccessTokenUtil.getUserId(request));
        } catch (Exception e) {
            return R.fail(0, e.getMessage());
        }
        return res ? R.success() : R.fail(ResponseEnum.PARAM_IS_INVAlID);
    }


    /**
     * 添加书籍节点
     * @param bookUpdateDto 书籍节点信息封装类
     * @param request http请求对象
     * @return 响应结果
     */
    @RequestMapping(method = RequestMethod.POST)
    public R addBookNode(@RequestBody @Valid BookUpdateDto bookUpdateDto, HttpServletRequest request){
        if (bookUpdateDto.getParentId() == null) {
            return R.fail(ResponseEnum.PARAM_IS_BLANK);
        }
        boolean res = bookService.addBookNode(bookUpdateDto, AccessTokenUtil.getUserId(request));
        return res ? R.success() : R.fail(ResponseEnum.PARAM_IS_INVAlID);
    }

    /**
     * 通过父节点ID获取当前节点下子书籍节点
     * @param parentId 书籍父节点
     * @return 响应结果
     */
    @RequestMapping(method = RequestMethod.GET)
    public R getBookNodesByParentId(Long parentId){
        if (parentId == null) {
            return R.fail(ResponseEnum.PARAM_IS_BLANK);
        }
        List<BookListResult> bookNodes = bookService.getBookNodes(parentId);
        return R.success(bookNodes);
    }

    /**
     * 修改书籍节点信息
     * @param bookUpdateDto 书籍信息修改封装类
     * @param request http请求对象
     * @return 响应结果
     */
    @RequestMapping(method = RequestMethod.PUT)
    public R modifyBookNodeInfo(@RequestBody @Valid BookUpdateDto bookUpdateDto, HttpServletRequest request){
        boolean res = bookService.modifyBookNodeInfo(bookUpdateDto, AccessTokenUtil.getUserId(request));
        return res ? R.success() : R.fail(ResponseEnum.PARAM_IS_INVAlID);
    }

    /**
     * 删除书籍节点
     * @param id 节点ID
     * @param request http请求对象
     * @return 响应结果
     */
    @RequestMapping(method = RequestMethod.DELETE)
    public R removeBookNode(Long id, HttpServletRequest request){
        boolean res = false;
        try {
            res = bookService.removeBookNode(id, AccessTokenUtil.getUserId(request));
        } catch (DatabaseOperationException e) {
            return R.fail(102, e.getMessage());
        }
        return res ? R.success() : R.fail(ResponseEnum.PARAM_IS_INVAlID);
    }

    /**
     * 根据书籍ID获取书籍节点信息
     * @param id 书籍节点ID
     * @return 书籍节点信息
     */
    @RequestMapping(value = "/info", method = RequestMethod.GET)
    public R getBookInfoById(@RequestParam Long id){
        Book book = bookService.getById(id);
        if (book == null){
            return R.fail(ResponseEnum.PARAM_IS_INVAlID);
        }
        BookListResult bookListResult = new BookListResult();
        BeanUtils.copyProperties(book, bookListResult);
        return R.success(bookListResult);
    }

    /**
     * 根据父节点获取子书籍节点，不统计题目数量
     * @param parentId 书籍父节点
     * @return 书籍子节点
     */
    @RequestMapping(value = "/simple", method = RequestMethod.GET)
    public R getBookNodesByParentIdWithoutItemNum(Long parentId){
        if (parentId == null) {
            return R.fail(ResponseEnum.PARAM_IS_BLANK);
        }
        return R.success(bookService.getBookNodesWithoutItemNum(parentId));
    }

    /**
     * 设置书籍节点封面
     * @param bookId 书籍节点ID
     * @param file 上传文件
     * @param request 请求对象
     * @return 处理结果
     */
    @RequestMapping(value = "/cover", method = RequestMethod.PUT)
    public R setBookNodeCoverImage(@RequestParam Long bookId, @RequestParam(required = false) MultipartFile file, HttpServletRequest request){
        Map<String, String> map = null;
        try {
            map = bookService.setBookNodeCoverImage(bookId, file, AccessTokenUtil.getUserId(request));
        } catch (Exception e) {
            return R.fail(0, e.getMessage());
        }
        return R.success(map);
    }
}
